//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================


using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.IO.Compression;
using System.IO.Packaging;
using System.Globalization;



namespace LitwareHR.Recruiting.Services
{

    /// <summary>
    /// Summary description for CompressionHelper
    /// </summary>
    public sealed class ZipHelper
    {
        private ZipHelper()
        {
        }

        private const long BUFFER_SIZE = 4096;

        public static void Compress(string sourcePath, string destinationFilePath)
        {
            if (!Directory.Exists(sourcePath))
            {
                throw new IOException(String.Format(CultureInfo.InvariantCulture, "The source path {0} was not found", sourcePath));
            }

            using (Package zip = Package.Open(destinationFilePath, FileMode.Create))
            {
                AddDirectoryElements(zip, sourcePath, String.Empty);
            }
           
        }

        private static void AddDirectoryElements(Package zip, string sourcePath, string zipRelativePath)
        {
            foreach (string element in Directory.GetFileSystemEntries(sourcePath))
            {
                // Directory
                if (Directory.Exists(element))
                {
                    string directoryName = element.Substring(element.LastIndexOf(Path.DirectorySeparatorChar) + 1);
                    AddDirectoryElements(zip, element, Path.Combine(zipRelativePath, directoryName));
                }
                // Files in directory
                else
                {
                    AddFileToZip(zip, element, zipRelativePath);
                }
            }
        }

        private static void AddFileToZip(Package zip, string fileToAddPath, string zipRelativePath)
        {
            string destFilename = String.Concat(".\\", Path.Combine(zipRelativePath, Path.GetFileName(fileToAddPath)) );
                        
            Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
            if (zip.PartExists(uri))
            {
                zip.DeletePart(uri);
            }

            CompressionOption option = CompressionOption.Normal;
            if (FileHelper.IsMediaFile(fileToAddPath))
            {
                option = CompressionOption.NotCompressed;
            }

            PackagePart part = zip.CreatePart(uri, String.Empty, option);
            using (FileStream fileStream = new FileStream(fileToAddPath, FileMode.Open, FileAccess.Read))
            {
                using (Stream dest = part.GetStream())
                {
                    CopyStream(fileStream, dest);
                }
            }
            
        }       

        private static void CopyStream(FileStream inputStream, Stream outputStream)
        {
            long bufferSize = inputStream.Length < BUFFER_SIZE ? inputStream.Length : BUFFER_SIZE;
            byte[] buffer = new byte[bufferSize];
            int bytesRead = 0;
            long bytesWritten = 0;
            while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                outputStream.Write(buffer, 0, bytesRead);
                bytesWritten += bufferSize;
            }
        }

    }

}


